package lumis.service.portalmanagement.systeminfo;

import lumis.doui.source.ISourceData;
import lumis.doui.source.Source;
import lumis.doui.source.TabularData;
import lumis.doui.source.postloadprocessor.IPostLoadProcessor;
import lumis.portal.PortalException;
import lumis.portal.authentication.SessionConfig;
import lumis.util.ITransaction;
import lumis.util.XmlUtil;

import org.w3c.dom.Node;

/**
 * A post load processor that replaces strings in the fields of the source.
 * The StringReplacePostLoadProcessor uses 3 parameters:
 * 	- from 		the string that will be replaced
 * 	- to 		the string that will replace
 * 	- fieldId	the field id where the replace will occur
 * StringReplacePostLoadProcessor has some constants. 
 * To use them, the attribute useConstant must be used with true and the 
 * parameter's value must be the constant name.
 * 
 * <p>
 * Example usage:
 * <xmp>
 *<postLoadProcessor className="lumis.service.portalmanagement.systeminfo.StringReplacePostLoadProcessor">
 *	<parameters>
 *		<parameter name="from">rigth</parameter>
 *		<parameter name="to">right</parameter>
 *		<parameter name="fieldId">fieldId</parameter>
 *	</parameters>
 *</postLoadProcessor>
 *</xmp> 
 *
 * <p>
 * Example to use StringReplacePostLoadProcessor's constants:
 * <xmp>
 *<postLoadProcessor className="lumis.service.portalmanagement.systeminfo.StringReplacePostLoadProcessor">
 *	<parameters>
 *		<parameter name="from" useConstant="true">SYSTEM_NEW_LINE</parameter>
 *		<parameter name="to" useConstant="true">HTML_BR</parameter>
 *		<parameter name="fieldId">fieldId</parameter>
 *	</parameters>
 *</postLoadProcessor> 
 * </xmp>
 *
 * @version $Revision: 11804 $ $Date: 2010-07-29 10:06:21 -0300 (Thu, 29 Jul 2010) $
 * @since 5.6.0
 */
public class StringReplacePostLoadProcessor implements IPostLoadProcessor 
{
	
	/** 
	 * the name of the parameter containing the string to be replaced 
	 * @since 5.6.0
	 */
	private static final String PARAMETER_FROM = "from";
	/** 
	 * the name of the parameter containing the string that will replace the 
	 * old one 
	 * @since 5.6.0
	 */
	private static final String PARAMETER_TO = "to";	
	/** 
	 * the name of the parameter containing the id of the field in that the 
	 * replace will be done 
	 * @since 5.6.0
	 */
	private static final String PARAMETER_FIELD = "fieldId";
	/** 
	 * the name of the attribute that indicates whether the parameter uses a 
	 * constant 
	 * @since 5.6.0
	 */
	private static final String ATTRIBUTE_CONSTANT = "useConstant";
	
	/**
	 * Enum containing the constants.
	 */
	public enum StringConstant 
	{
		/**
		 * The system line separator string.
		 * @since 5.6.0
		 */
		SYSTEM_NEW_LINE (System.getProperty("line.separator")),
		/**
		 * The HTML BR element.
		 * @since 5.6.0
		 */
		HTML_BR			("<br/>");
		
		private final String value;
		
		StringConstant(String value) 
		{
			this.value = value;
		}
	}
	
	public void processSource(SessionConfig sessionConfig, 
								Source source, Node parametersNode, 
								ITransaction transaction) 
							throws PortalException 
	{
		String fromString = readParameterValue(PARAMETER_FROM, parametersNode);
		String toString = readParameterValue(PARAMETER_TO, parametersNode);
		String fieldId = readParameterValue(PARAMETER_FIELD, parametersNode);
		
		replaceStrings(source, fieldId, fromString, toString);
	}

	/**
	 * Reads the value of a given parameter using its name.
	 * @param parameterName		parameter's name.
	 * @param parametersNode	parent node.
	 * @return					the string value of the parameter.
	 * @throws PortalException	whenever an error occur.
	 * @since 5.6.0
	 */
	protected String readParameterValue(String parameterName, 
										Node parametersNode) 
									throws PortalException 
	{
		String query = "parameter[@name='" + parameterName + "']";
		
		String parameterValue = XmlUtil.readNodeString(query, parametersNode);
		Node node = XmlUtil.selectSingleNode(query, parametersNode);
		boolean useConstant = XmlUtil.readAttributeBoolean(ATTRIBUTE_CONSTANT, node);
		
		if (useConstant) 
		{
			parameterValue = StringConstant.valueOf(parameterValue).value;
		}
		
		return parameterValue;
	}
	
	/**
	 * Replace the from string by the to string in a field of a source.
	 * @param source		the source instance.
	 * @param fieldId		the id of the desired field.
	 * @param from			the string that will be replaced.
	 * @param to			the string that will replace.
	 * @throws PortalException whenever an error occur.
	 * @since 5.6.0
	 */
	protected void replaceStrings(Source<?> source, 
									String fieldId, 
									String from, 
									String to) 
							throws PortalException 
	{
		TabularData tabularData = (TabularData) source.getData();
		for(ISourceData row : tabularData.getRows())
		{			
			String fieldValue = row.get(fieldId, String.class);			
			row.put(fieldId, fieldValue.replaceAll(from, to));
		}		
	}
	
}
